package changceilingcolor003;

import java.util.ArrayList;
import java.util.HashMap;

import controlP5.Slider;
import controlP5.Toggle;

import toxi.geom.Vec2D;
import toxi.geom.Vec3D;

public class Attraction extends Actors {
	private String m_id;
	private String m_description;
	private int m_R;
	private int m_G;
	private int m_B;
	public int m_Min_x = 0;
	public int m_Max_x = 0;
	public int m_Min_y = 0;
	public int m_Max_y = 0;
	public int m_Min_z = 0;
	public int m_Max_z = 0;
	public int m_Min_r = 0;
	public int m_Max_r = 0;
	
	public int output_area=0;
	public int output_countpeople=0;
	public int output_duration=0;
	public Vec3D output_direction;
	public int countTime=0;
	public int timerfixed=0;
	public int timer=1;
	
	
	// private float m_MinDistanceFromConnectAttraction = 0;
	// private float m_MaxDistanceFromConnectAttraction = 0;
	public ArrayList<Actors> m_ConnectedAttractors = new ArrayList<Actors>();

	//private boolean m_bLocationChanged = false;
	private boolean m_bIsInLigalLocation = false;
	private boolean m_bVisualAlarmState = false;
	private double m_AlaramRadios = 0;
	private double m_AlaramStrenght = 0;
	private boolean m_bAlarmBecauseIsOtherTooClose = false;
	private ArrayList<String> m_PreferedAttractors = new ArrayList<String>();
	private int MaxNumberOfConnectedAttractors =0; 
	public int m_visited =-1;
	public Boolean m_bIsExist = false;
	public Boolean m_bIsEntrance = false;
	public Boolean m_bIsExit = false;
	
	//int m_nMassRadios = 80;		
	int m_nMassRadios = 160;		
	private Vec3D m_TransformationTo = null;
	
	Slider m_range_Slider = null;
	Slider m_x_Slider = null;
	Slider m_y_Slider = null;
	Slider m_z_Slider = null;
	Toggle m_isActiveToggle = null;
	
	
	
	public void SetRelatedGUIElements(Toggle isActiveToggle, Slider range_Slider, Slider x_Slider, Slider y_Slider, Slider z_Slider)
	{
		m_range_Slider = range_Slider ;
		m_x_Slider = x_Slider ;
		m_y_Slider = y_Slider;
		m_z_Slider = z_Slider;
		m_isActiveToggle = isActiveToggle;
		
		
		
	}
	
	Vec3D m_oldLocation = new Vec3D();

	Attraction(ChangCeilingColor003 parent, String ID, String description,
			int R, int G, int B, int Radious, Vec3D minPos, Vec3D maxPos, int Min_r, int Max_r,
			Vec3D _location) {
		super(parent, _location);
		m_R = R;
		m_G = G;
		m_B = B;
		m_active = false;
		m_Min_x = (int) minPos.x;
		m_Max_x = (int) maxPos.x;
		m_Min_y = (int) minPos.y;
		m_Max_y = (int) maxPos.y;
		m_Min_z = (int) minPos.z;
		m_Max_z = (int) maxPos.z;
		m_Min_r = Min_r;
		m_Max_r = Max_r;
		m_oldLocation = GetLocation();

		m_id = ID;
		SelfAttrationList.put("ArtScent", 5.0);
		AttractionRadious = Radious;
		InterestDuration = 50;
		m_description = description;		
	}
	
	public void AddAttractorToPreferdList(String attractorId)
	{
		m_PreferedAttractors.add(attractorId);
	}
	
	public void SetMinPos(Vec3D minPos)
	{
		m_Min_x = (int) minPos.x;
		m_Min_y = (int) minPos.y;		
		m_Min_z = (int) minPos.z;				
	}
	
	public void SetMaxPos(Vec3D maxPos)
	{		
		m_Max_x = (int) maxPos.x;		
		m_Max_y = (int) maxPos.y;	
		m_Max_z = (int) maxPos.z;
	}
	
	public void SetTransformation(Vec3D to)
	{
		
		m_TransformationTo = to;
		
	}
	
	public void Transform(Actors actorToTransform)
	{
		if(m_TransformationTo  != null)
		{
			actorToTransform.SetLocation( actorToTransform.GetLocation().add(m_TransformationTo));
			
		}		
	}	
	
	public void setMassRadios(int nMassRadios)
	{
		m_nMassRadios = nMassRadios;
	}
	
	public void UpdateTemperature()
	{
		if(!m_active)
			return ;
		
		
		for(int x = -1*m_nMassRadios ; x <m_nMassRadios ; ++x)
		{
			for(int y = -1*m_nMassRadios ; y < m_nMassRadios  ; ++y)
			{
				
				int new_x = (int)(x + GetLocation().x);
				int new_y = (int)(y + GetLocation().y);
				
				if ( (new_x <1) || (new_x > (p5.width -1 ) ) || (new_y > (p5.height -1 )) || (new_y < 1 ) )
				{
					continue;
				}
				
				
				
				if((x == 0) && (y == 0)) 
					continue;
				
				double  distance_from_center =Math.sqrt( Math.pow(x, 2 ) + Math.pow(y,2) );
				
				
				if(distance_from_center >m_nMassRadios )
					continue;
				
				p5.TemperatureGrid[new_x ][new_y][m_nCurrentFloor] +=(int)(-1* (((m_nMassRadios-distance_from_center)/m_nMassRadios)*100));
			}
		}
	}
	
	public void SetMaxNumberOfConnection(int numberOfConnection)
	{
		MaxNumberOfConnectedAttractors = numberOfConnection;
	}

	public void OnChangeLocationEvent() 
	{
		if(m_oldLocation != GetLocation())
		{
			p5.PausePeople = true;
			//m_bLocationChanged = true;			
		}
	}
	
	public void SetLocationAndUpdateGUI(Vec3D v)
	{
		SetLocation(v);
		
		if((m_x_Slider != null) &&(m_y_Slider != null) &&(m_z_Slider!= null))
		{
			m_x_Slider.setValue( GetLocation().x );
			m_y_Slider.setValue( GetLocation().y );
			m_z_Slider.setValue( GetLocation().z );	
		}	

	}
	
	public void SetRangeAndUpdateGUI(double newAttractionRange)
	{
		AttractionRadious = newAttractionRange;
		
		if( m_range_Slider != null)
		{
			m_range_Slider.setValue((float) AttractionRadious);
		}	

	}
	
	public void SetIsActiveAndUpdateGUI(Boolean isActive)
	{		
		m_active = isActive;	
	}
	
	public boolean AllowToConnectIfPossible(Attraction otherAttractor)
	{
		
		if(m_ConnectedAttractors.size() < this.MaxNumberOfConnectedAttractors && !m_ConnectedAttractors.contains(otherAttractor) )
		{			
			return true;
		}
		return false;
	}
	//
	@Override
	public void update(World w) {
		
		
		if (!m_active)
			return;
		//m_oldLocation != GetLocation() ||
		//if ( p5.m_IsInInitPhase || p5.m_IsInEtAttractionStatePhase) 
		{
			
			p5.print(this.GetId()+ "-");
			
			//m_bLocationChanged = false;
			m_bIsInLigalLocation = true;
			
			for (int i = 0; i < p5.alisDst.size(); i++) {
				
				
				Attraction examinedAttractor = (Attraction) p5.alisDst.get(i);
				
				if (p5.alisDst.get(i) == this || !(p5.alisDst.get(i).m_active))
					continue;


				{
					for(int j=0; j< m_PreferedAttractors.size() ;++j)
					{
						
							String sExaminedId = m_PreferedAttractors.get(j);
						if(examinedAttractor.m_id.equals(sExaminedId) &&
								(m_ConnectedAttractors.size() < this.MaxNumberOfConnectedAttractors  ) &&
								examinedAttractor.AllowToConnectIfPossible(this) )
						{			
							p5.print("->"+examinedAttractor.GetId());
							examinedAttractor.m_ConnectedAttractors.add(this);			
							m_ConnectedAttractors.add(examinedAttractor);
							break;
						}
					}
					
					
					
				}

			}
			
			p5.println();
		}
//		else {
//			return;
//		}
		
		
	}

	@Override 
	public void Draw() {
////////THIS IS THE LINE WHICH CONNECTS BETWEENT HE ATTRACTORS
		if (!m_active)
			return;
		Vec3D v = GetLocation();
		//p5.stroke(0, 255, 255,60);////////////////////////////////////////////////////
		p5.stroke(0, 255, 255);
		//p5.stroke(150, 150, 150);
		p5.strokeWeight(1);
		Vec3D MyLocation = GetLocation();
		for (int i = 0; i < m_ConnectedAttractors.size(); ++i) {			
			Vec3D OtherLocation = m_ConnectedAttractors.get(i).GetLocation();
			if(p5.showDetail){
			p5.line(MyLocation.x, MyLocation.y, MyLocation.z+1, OtherLocation.x,
					OtherLocation.y, OtherLocation.z+1);// /////////////////////////////
			}
		}

		
		//p5.ellipse(v.x, v.y,10, 10);// .point(v.x, v.y, v.z);
		p5.noStroke();
		//p5.lights();
		p5.translate(v.x, v.y, v.z);
		
		if(p5.m_ShouldShowAttractorsRange)
		{
			p5.fill(m_R, m_G, m_B,30);///////////////////////////////////////
			p5.sphere((float) AttractionRadious);	
		}
		else
		{
			p5.fill(m_R, m_G, m_B);
			p5.sphere((float) 2.5); ///////////for siteA//////////////////////////////
			//p5.sphere((float) 15); ///////////for siteB
		}
		
		p5.noFill();
	       for (int j=1;j<20;j++) {
	        	p5.stroke(m_R, m_G, m_B, 100-j*5);
	     //strokeWeight(10-j);
	        	p5.strokeWeight(3);
	        	//p5.strokeWeight(2000/(float)AttractionRadious);
	        	p5.ellipse(0, 0, j*(float) AttractionRadious*1/8, j*(float) AttractionRadious*1/8);
	   }
		p5.translate(-v.x, -v.y, -v.z);
	
		
		
 
		//p5.strokeWeight(3);
		// p5.ellipse(v.x, v.y, (float)AttractionRadious*2,
		// (float)AttractionRadious*2);//////////////////////////////////////////////////////////////////
		p5.fill(255);
		//p5.textSize(30);///////////////////////////////only for SiteB
		p5.pushMatrix();
		p5.translate(0, 0, 	GetLocation().z);	
		p5.text(m_id, GetLocation().x+5, GetLocation().y);
		
		if (p5.Somemeasurement) {
			
			//p5.text(m_description, GetLocation().x+5, GetLocation().y);
			////////////////////draw measurement
			p5.stroke(100, 100, 100);
			p5.strokeWeight(1);
			//p5.line(GetLocation().x, GetLocation().y, 6, GetLocation().y);
			//p5.line(GetLocation().x, GetLocation().y, GetLocation().x,6);
			
			p5.line(GetLocation().x, GetLocation().y, 0,GetLocation().y);
			p5.line(GetLocation().x, GetLocation().y, GetLocation().x,0);

			p5.pushMatrix();			
			p5.stroke(150, 150, 150,80);
			p5.strokeWeight(1);
		    p5.translate(6, GetLocation().y);
		    p5.rotate(p5.radians(270));
		    p5.beginShape();
		    p5.vertex(0, -2*2);
		    p5.vertex(-2, 2*2);
		    p5.vertex(2, 2*2);
		    p5.endShape();
		    p5.popMatrix();
		    p5.stroke(150, 150, 150,80); 
		    p5.text((int)GetLocation().x, GetLocation().x/2, GetLocation().y);
		    
		    
		    
		    
		    p5.pushMatrix();			
			p5.stroke(150, 150, 150,80);
			p5.strokeWeight(1);
		    p5.translate(GetLocation().x,6);
		    p5.rotate(p5.radians(0));
		    p5.beginShape();
		    p5.vertex(0, -2*2);
		    p5.vertex(-2, 2*2);
		    p5.vertex(2, 2*2);
		    p5.endShape();
		    p5.popMatrix();
		    
		    p5.text((int)GetLocation().y, GetLocation().x, GetLocation().y/2);

		}
		
		p5.popMatrix();	

		if (!m_bIsInLigalLocation) {
			ShowAlaram();
		} else {
			m_bVisualAlarmState = false;

		}

	}

	private void ShowAlaram() {
		if (!p5.showAlarm)
			return;
		// make sure the object blink every 10 frames
		m_bVisualAlarmState = true;

		if (m_bVisualAlarmState) {

			Vec3D v = GetLocation();

			if (m_bAlarmBecauseIsOtherTooClose) {
				p5.fill(150, 0, 0,100);
			} else {
				// p5.strokeWeight((float) m_AlaramStrenght);
				p5.stroke(255, 0, 0);
			}

			p5.ellipse(v.x, v.y, (float) m_AlaramRadios * 2,
					(float) m_AlaramRadios * 2);
			p5.noFill();
		}
	}

	@Override
	double GetIntrestDuration() {

		return InterestDuration;
	}

	public String GetId() {
		return m_id;
	}

	public String GetDescription() {
		return m_description;
	}

	// get color
	public int GetColorR() {
		return m_R;
	}

	public int GetColorG() {
		return m_G;
	}

	public int GetColorB() {
		return m_B;
	}
	public int GetArea() {
		return output_area;
	}

	public int GetPeople() {
		return output_countpeople;
	}
	public int GetDuration() {
		return output_duration;
	}
	
	@Override
	public double GetAttractionRadious() {
		return AttractionRadious;
	}

}
